package com.tyf.bookreader.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tyf.bookreader.domain.BrComment;
import com.tyf.bookreader.dto.CommentDTO;
import com.tyf.bookreader.dto.CommentStarDto;
import com.tyf.bookreader.dto.PageRespDto;
import com.tyf.bookreader.manager.CommentCacheManager;
import com.tyf.bookreader.mapper.BrCommentMapper;
import com.tyf.bookreader.mapper.BrUserMapper;
import com.tyf.bookreader.service.CommentService;
import com.tyf.bookreader.service.RedisService;
import com.tyf.bookreader.utils.UserUtils;
import com.tyf.bookreader.vo.CommentPageVo;
import com.tyf.bookreader.component.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * @Description 评论业务实现类
 * @Author shallow
 * @Date 2023/4/3 16:58
 */

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private BrCommentMapper commentMapper;

    @Autowired
    private BrUserMapper userMapper;

    @Autowired
    private RedisService redisService;

    @Autowired
    private CommentCacheManager commentCacheManager;


    @Override
    public Result<PageRespDto<CommentDTO>> getAllCommentByBookId(CommentPageVo commentPageVo) {
        //查询评论总量
        Long bookId = commentPageVo.getBookId();
        int sort = commentPageVo.getSort();
        int pageNum = commentPageVo.getPageNum();
        int pageSize = commentPageVo.getPageSize();
        Integer count = commentMapper.selectCount(new LambdaQueryWrapper<BrComment>()
                .eq(BrComment::getBookId, bookId)
                .eq(BrComment::getParentId,0));
        List<BrComment> commentList;
        if (count == 0){
            return Result.ok();
        }
        if (sort == 0){
             commentList = commentMapper.selectList(new LambdaQueryWrapper<BrComment>()
                     .eq(BrComment::getBookId, bookId)
                     .eq(BrComment::getParentId,0)
                     .orderByDesc(BrComment::getCommentStars));
        }else{
            commentList = commentMapper.selectList(new LambdaQueryWrapper<BrComment>()
                    .eq(BrComment::getBookId, bookId)
                    .eq(BrComment::getParentId,0)
                    .orderByDesc(BrComment::getCreateTime));
        }

        //
        List<CommentDTO> commentDTOList = getCommentDtoList(commentList);
        return Result.ok(new PageRespDto<>(pageNum, pageSize, count, commentDTOList));
    }



    @Override
    public Result<List<CommentDTO>> getHotCommentsById(Long bookId) {
        Integer count = commentMapper.selectCount(new LambdaQueryWrapper<BrComment>()
                .eq(BrComment::getBookId, bookId)
                .eq(BrComment::getParentId,0));
        if (count == 0){
            return Result.ok();
        }
        List<BrComment>  commentList = commentMapper.selectList(new LambdaQueryWrapper<BrComment>()
                    .eq(BrComment::getBookId, bookId)
                    .eq(BrComment::getParentId,0)
                    .orderByDesc(BrComment::getCommentStars)
                    .last("limit 5"));
        List<CommentDTO> commentDtoList = getCommentDtoList(commentList);

        return Result.ok(commentDtoList);
    }

    private List<CommentDTO> getCommentDtoList(List<BrComment> commentList) {
        List<CommentDTO> commentDTOList = commentList.stream().map(v -> {
            String userName = userMapper.selectById(v.getUserId()).getUserName();
            String userImg = userMapper.selectById(v.getUserId()).getUserImg();
            Integer commentStars = commentCacheManager.getStarsById(v.getId());
            return CommentDTO.builder()
                    .id(v.getId())
                    .userId(v.getUserId())
                    .userName(userName)
                    .userImg(userImg)
                    .createTime(v.getCreateTime())
                    .commentContent(v.getCommentContent())
                    .parentId(v.getParentId())
                    .commentStars(commentStars).build();

        }).toList();
        return commentDTOList;
    }

    @Override
    public Result<PageRespDto<CommentDTO>> getChildComment(CommentPageVo commentPageVo) {
        Long parentId = commentPageVo.getParentId();
        int pageNum = commentPageVo.getPageNum();
        int pageSize = commentPageVo.getPageSize();
        BrComment comment = commentMapper.selectById(parentId);
        if (Objects.isNull(comment)){
            return Result.ok();
        }
        List<BrComment> commentList = commentMapper.selectList(new LambdaQueryWrapper<BrComment>()
                .eq(BrComment::getParentId, parentId));
        commentList.stream().forEach(v->{
            Integer starNum = commentCacheManager.getStarsById(v.getId());
            v.setCommentStars(starNum);
        });
        Collections.sort(commentList,(o1,o2)-> (int) (o1.getCommentStars()-o2.getCommentStars()));
        List<CommentDTO> commentDtoList = getCommentDtoList(commentList);
        return Result.ok(new PageRespDto<>(pageNum,pageSize,commentDtoList.size(),commentDtoList));
    }

    @Override
    public Result saveCommentLike(Long commentId) {
        CommentStarDto commentStarDto = commentCacheManager.starsComment(commentId, UserUtils.getLoginUser().getUser().getId());
        return Result.ok(commentStarDto.getCommentStars(),commentStarDto.getMessage());
    }
}
